package org.lyu.util;

import java.math.BigInteger;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 使用C3P0数据库连接池 & apache commons-dbutils
 * @author w
 *
 */
public class MyDbUtils3 {
	
	private static ComboPooledDataSource cpds = new ComboPooledDataSource();
	
	/**
	 * 获取数据源
	 * @return c3p0数据源
	 */
	public static DataSource getDataSource() {
		return cpds;
	}

	/**
	 * 获取数据库连接Connection
	 * @return Connection
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return cpds.getConnection();
	}
	
	/**
	 * 
	 * 使用commons-dbutils查询所有记录
	 * 
	 * @param <T> 声明 T是个泛型类型
	 * @param clazz T.class
	 * @param sql sql语句 
	 * @return List or null
	 */
	public static <T> List<T> excuteQueryForList(Class<T> clazz, String sql) {
		
		QueryRunner queryRunner = new QueryRunner(cpds);
		
		BeanListHandler<T> handler = new BeanListHandler<T>(clazz);
		
		List<T> result = null;
		try {
			result = queryRunner.query(sql, handler);
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
		
		return result;
		
	}
	
	/**
	 * 使用commons-dbutils查询部分记录
	 * @param <T> 声明 T是个泛型类型
	 * @param clazz T.class
	 * @param sql sql语句
	 * @param args 参数
	 * @return List or null
	 */
	public static <T> List<T> excuteQueryForList(Class<T> clazz,String sql, Object... args) {
		QueryRunner queryRunner = new QueryRunner(cpds);
		
		BeanListHandler<T> handler = new BeanListHandler<T>(clazz);
		
		List<T> result = null;
		try {
			result = queryRunner.query(sql, handler, args);
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
		
		return result;
	}
	
	/**
	 * 
	 * 使用commons-dbutils查询一个记录
	 * 
	 * @param <T> 声明 T是个泛型类型
	 * @param clazz T.class
	 * @param sql sql语句 
	 * @param args 参数
	 * @return T or null
	 */
	public static <T> T excuteQueryForOne(Class<T> clazz, String sql, Object... args) {
		
		QueryRunner queryRunner = new QueryRunner(cpds);
		
		BeanHandler<T> handler = new BeanHandler<T>(clazz);
		
		T result = null;
		try {
			result = queryRunner.query(sql, handler, args);
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
		
		return result;
		
	}
	
	/**
	 * 封装修改操作
	 * @param sql sql语句
	 * @param args 参数
	 * @return 受影响的行数
	 */
	public static int excuteUpdate(String sql, Object... args) {
		QueryRunner queryRunner = new QueryRunner(cpds);
		
		
		int result = 0;
		try {
			result = queryRunner.update(sql, args);
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
		
		return result;
	}
	
	/**
	 * 如果没有设置主键自增，使用excuteUpdate添加数据
	 * @param sql sql语句
	 * @param args 参数
	 * @return 自动生成的主键
	 */
	public static Long excuteInsert(String sql, Object... args) {
		QueryRunner queryRunner = new QueryRunner(cpds);
		
		try {
			BigInteger result = queryRunner.insert(sql, new ScalarHandler<BigInteger>(), args);
			return result.longValue();
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
		return null;
	}
	
}
